# -*- coding: utf-8 -*-

import json
import hashlib
import re
import time
import uuid
from datetime import datetime, timedelta
# from random import choice
import decimal
from Crypto.Cipher import AES
import base64
import random

class JsonEncoder(json.JSONEncoder):
    def default(self, obj):

        if isinstance(obj, decimal.Decimal):
            return float(obj)
        elif isinstance(obj, datetime):
            return Utils.format_datetime(obj)

        super(JsonEncoder, self).default(obj)


class aescrypt():
    def __init__(self, key, model, iv, encode_):
        self.encode_ = encode_
        self.model = {'ECB': AES.MODE_ECB, 'CBC': AES.MODE_CBC}[model]
        self.key = self.add_16(key)
        if model == 'ECB':
            self.aes = AES.new(self.key, self.model)
        elif model == 'CBC':
            self.aes = AES.new(self.key, self.model, iv)

    def add_16(self, par):
        par = par.encode(self.encode_)
        while len(par) % 16 != 0:
            par += b'\x00'
        return par

    def encrypt(self, text):
        text = self.add_16(text)
        self.encrypt_text = self.aes.encrypt(text)
        return base64.encodebytes(self.encrypt_text).decode().strip()

    def decrypt(self, text):
        text = base64.decodebytes(text.encode(self.encode_))
        self.decrypt_text = self.aes.decrypt(text)
        return self.decrypt_text.decode(self.encode_).strip('\0')


class Utils(object):

    @staticmethod
    def escape_string(value):
        value = value.replace('\\', '\\\\')
        value = value.replace('\0', '\\0')
        value = value.replace('\n', '\\n')
        value = value.replace('\r', '\\r')
        value = value.replace('\032', '\\Z')
        value = value.replace("'", "\\'")
        value = value.replace('"', '\\"')
        return value

    @staticmethod
    def is_null(text):
        result = False
        if text.strip() == '':
            result = True
        return result

    @staticmethod
    def is_email(email):
        result = False
        if email and re.match(
                '^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$',
                email):
            result = True
        return result

    @staticmethod
    def is_expire(time):
        '''
        判断时间是否大于当前时间
        :param time:
        :return:
        '''
        now = str(datetime.now())
        if now > time:
            return True
        else:
            return False

    @staticmethod
    def getDateAfter(day):
        '''
        获得指定时间之后的时间
        :param day: 天
        :return:
        '''
        now = datetime.now()
        return now + timedelta(days=day)

    @staticmethod
    def get_token():
        now = str(int(time.time())).encode('utf-8')
        uud = str(uuid.uuid1()).encode('utf-8')
        m = hashlib.md5()
        m.update(uud + now)
        return str(m.hexdigest())

    @staticmethod
    def get_uuid():
        return str(uuid.uuid4().hex)

    @staticmethod
    def md5(str):
        m = hashlib.md5()
        m.update(str.encode('utf8'))
        return m.hexdigest()

    @staticmethod
    def is_length(small, big, text):
        text = len(text)
        if small <= text <= big:
            return True
        else:
            return False

    @staticmethod
    def encode(obj):
        return json.dumps(obj, cls=JsonEncoder)

    @staticmethod
    def is_number(number):
        result = False
        if number and str(number).isdigit():
            result = True
        return result

    @staticmethod
    def get_checkcode(digit=4, integer=True):
        checkcode = ''
        for i in range(digit):
            index = random.randrange(0, 5)
            if index != i and index + 1 != i and not integer:
                checkcode += chr(random.randint(97, 122))
            else:
                checkcode += str(random.randint(1, 9))
        return checkcode

    @staticmethod
    def format_time(datatime):
        return datatime.strftime('%Y-%m-%d %H:%S:%M')

    @staticmethod
    def str_format_time(str, time_format='%Y-%m-%d %H:%M:%S'):
        return datetime.strptime(str, time_format)


    @staticmethod
    def get_nowtime():
        return str(datetime.now())

    @staticmethod
    def timestamp():
        return int(time.mktime(time.localtime()))
        #int(round(time.time() * 1000))
    @staticmethod
    def format_year_month(date_obj, split='-'):
        '''
        格式化成 yyyy-MM
        :param date_obj: 日期对象
        :param split: 年月分割符
        :return: 格式化后的字符串
        '''
        if not date_obj:
            return ''
        return date_obj.strftime('%Y' + split + '%m')

    @staticmethod
    def format_datetime(date_obj, split='-', split2=':', space=' '):
        '''
        格式化成 yyyy-MM-dd HH:MM:SS
        :param space: 年月日与时间分割符号
        :param split2: 时间分割符
        :param date_obj: 日期对象
        :param split: 年月日分割符
        :return: 格式化后的字符串
        '''
        if not date_obj:
            return ''
        return date_obj.strftime('%Y' + split + '%m' + split + '%d' + space +
                                 '%H' + split2 + '%M' + split2 + '%S')

    @staticmethod
    def format_datetime_short(date_obj, split='-', split2=':', space=' '):
        '''
        格式化成 yyyy-MM-dd HH:MM
        :param space: 年月日与时间分割符号
        :param split2: 时间分割符
        :param date_obj: 日期对象
        :param split: 年月日分割符
        :return: 格式化后的字符串
        '''
        if not date_obj:
            return ''
        return date_obj.strftime('%Y' + split + '%m' + split + '%d' + space +
                                 '%H' + split2 + '%M')

    @staticmethod
    def format_date(date_obj, split='-'):
        '''
        格式化成 yyyy-MM-dd
        :param date_obj: 日期对象
        :param split: 年月日分割符
        :return: 格式化后的字符串
        '''
        if not date_obj:
            return ''
        try:
            return date_obj.strftime('%Y' + split + '%m' + split + '%d')
        except Exception as ex:
            print(ex)
        return ''

    @staticmethod
    def aes():
        return aescrypt('*&24341&……#@34)#!4', 'ECB', '', 'utf8')
